#include "MainProcess.h"
#include "args.hxx"
#include <string>
#include "memorymapping.h"




/**
 * @brief 项目名称定义
 */
#define PROJECT ("NodeCanvas")
/**
 * @brief 软件版本号定义
 */
#define VERSION (1.0)



int main_func(int argc, char** argv){
    /**
     * @brief 命令行参数解析器初始化
     * @param 程序功能描述和使用示例
     */
    args::ArgumentParser parser("该程序用于从需求文档中找出与目标需求相关联的上下游需求.", "使用示例: ./NodeCanvas.exe [-c] [-s] [-a] -d D:/Requiremets -t OBCU_SuRS_4327");
    args::HelpFlag help(parser, "help", "\t\t\t\t\t\t\t\t显示帮助文档", {'h',
         "help"});
    args::Flag version(parser, "Version", "\t\t\t\t\t\t\t\t显示软件版本", {'v', 'V', "version"});
    args::Flag acceptFlag(parser, "acceptflag", "\t\t\t\t\t\t\t\t接受文档修改并修改为读写模式", {'a', 'A', "Accept"});
    args::Flag searchFlag(parser, "searchflag", "\t\t\t\t\t\t\t\t搜索模式", {'s', 'S', "Search"});
    args::Flag clientFlag(parser, "clientflag", "\t\t\t\t\t\t\t\t客户进程标志", {'c', 'C', "Client"});
    args::ValueFlag<std::string> docPath(parser, "文档目录", "输入文件所在路径", {'d', 'D'});
    args::ValueFlag<std::string> targetKey(parser, "目标需求", "\t\t\t\t需要搜索的需求编号", {'t', 'T'});
    try
    {
        parser.ParseCLI(argc, argv);
    }
    catch (args::Help&)
    {
        std::cout << parser;
        return EXIT_SUCCESS;
    }
    catch (args::ParseError e)
    {
        std::cerr << e.what() << std::endl;
        std::cerr << parser;
        return EXIT_FAILURE;
    }
    catch (args::ValidationError e)
    {
        std::cerr << e.what() << std::endl;
        std::cerr << parser;
        return EXIT_FAILURE;
    }

    if (version) { 
        std::cout << "Name: " << PROJECT << std::endl;
        std::cout << "Version: " << std::fixed << std::setprecision(1) << VERSION << std::endl;
        std::cout << "Date: " << __DATE__ << std::endl;
        return EXIT_SUCCESS;
    }

    if (!docPath || !targetKey) {
        std::cerr << "请提供文档目录和目标需求编号." << std::endl;
        std::cerr << parser;
        return EXIT_FAILURE;
    }
    bool accept_flag = false, client_Flag = false, search_flag = false;
    if(acceptFlag) accept_flag = true;

    if(clientFlag) client_Flag = true;

    if(searchFlag) search_flag = true;

    run(args::get(docPath), args::get(targetKey), accept_flag, client_Flag, search_flag); 

    return EXIT_SUCCESS; // Exit the program with success status.
}

namespace fs = std::filesystem;

// 获取可执行文件所在目录
fs::path getExecutableDirectory() {
#ifdef _WIN32
    // Windows 平台
    char buffer[MAX_PATH];
    GetModuleFileNameA(NULL, buffer, MAX_PATH);
    return fs::path(buffer).parent_path();
#else
    // Linux/macOS 平台
    char buffer[1024];
    ssize_t len = readlink("/proc/self/exe", buffer, sizeof(buffer) - 1);
    if (len != -1) {
        buffer[len] = '\0';
        return fs::path(buffer).parent_path();
    }
    // 备用方案：从命令行参数获取（需要从main传递argv[0]）
    return fs::path("").parent_path();
#endif
}


/**
 * @brief 程序主入口函数
 * @param argc 命令行参数数量
 * @param argv 命令行参数数组
 * @return 程序退出状态码，0表示成功，非0表示错误
 * @note 负责解析命令行参数并启动需求追溯主流程
 */
int main(int argc, char** argv) {
    fs::path work_path = getExecutableDirectory();
    readConfig((work_path/"config.json").string());
    return main_func(argc, argv);
    
}